home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 March / PCWorld_2007-03_cd.bin / domacnost a kancelar / scribus / scribus-1.3.3.7-win32-install.exe / lib / whichdb.py < prev    next >
Text File  |  2004-11-03  |  3KB  |  118 lines

  1. # !/usr/bin/env python
  2. """Guess which db package to use to open a db file."""
  3.  
  4. import os
  5. import struct
  6. import sys
  7.  
  8. try:
  9.     import dbm
  10.     _dbmerror = dbm.error
  11. except ImportError:
  12.     dbm = None
  13.     # just some sort of valid exception which might be raised in the
  14.     # dbm test
  15.     _dbmerror = IOError
  16.  
  17. def whichdb(filename):
  18.     """Guess which db package to use to open a db file.
  19.  
  20.     Return values:
  21.  
  22.     - None if the database file can't be read;
  23.     - empty string if the file can be read but can't be recognized
  24.     - the module name (e.g. "dbm" or "gdbm") if recognized.
  25.  
  26.     Importing the given module may still fail, and opening the
  27.     database using that module may still fail.
  28.     """
  29.  
  30.     # Check for dbm first -- this has a .pag and a .dir file
  31.     try:
  32.         f = open(filename + os.extsep + "pag", "rb")
  33.         f.close()
  34.         # dbm linked with gdbm on OS/2 doesn't have .dir file
  35.         if not (dbm.library == "GNU gdbm" and sys.platform == "os2emx"):
  36.             f = open(filename + os.extsep + "dir", "rb")
  37.             f.close()
  38.         return "dbm"
  39.     except IOError:
  40.         # some dbm emulations based on Berkeley DB generate a .db file
  41.         # some do not, but they should be caught by the dbhash checks
  42.         try:
  43.             f = open(filename + os.extsep + "db", "rb")
  44.             f.close()
  45.             # guarantee we can actually open the file using dbm
  46.             # kind of overkill, but since we are dealing with emulations
  47.             # it seems like a prudent step
  48.             if dbm is not None:
  49.                 d = dbm.open(filename)
  50.                 d.close()
  51.                 return "dbm"
  52.         except (IOError, _dbmerror):
  53.             pass
  54.  
  55.     # Check for dumbdbm next -- this has a .dir and a .dat file
  56.     try:
  57.         # First check for presence of files
  58.         os.stat(filename + os.extsep + "dat")
  59.         size = os.stat(filename + os.extsep + "dir").st_size
  60.         # dumbdbm files with no keys are empty
  61.         if size == 0:
  62.             return "dumbdbm"
  63.         f = open(filename + os.extsep + "dir", "rb")
  64.         try:
  65.             if f.read(1) in ["'", '"']:
  66.                 return "dumbdbm"
  67.         finally:
  68.             f.close()
  69.     except (OSError, IOError):
  70.         pass
  71.  
  72.     # See if the file exists, return None if not
  73.     try:
  74.         f = open(filename, "rb")
  75.     except IOError:
  76.         return None
  77.  
  78.     # Read the start of the file -- the magic number
  79.     s16 = f.read(16)
  80.     f.close()
  81.     s = s16[0:4]
  82.  
  83.     # Return "" if not at least 4 bytes
  84.     if len(s) != 4:
  85.         return ""
  86.  
  87.     # Convert to 4-byte int in native byte order -- return "" if impossible
  88.     try:
  89.         (magic,) = struct.unpack("=l", s)
  90.     except struct.error:
  91.         return ""
  92.  
  93.     # Check for GNU dbm
  94.     if magic == 0x13579ace:
  95.         return "gdbm"
  96.  
  97.     # Check for old Berkeley db hash file format v2
  98.     if magic in (0x00061561, 0x61150600):
  99.         return "bsddb185"
  100.  
  101.     # Later versions of Berkeley db hash file have a 12-byte pad in
  102.     # front of the file type
  103.     try:
  104.         (magic,) = struct.unpack("=l", s16[-4:])
  105.     except struct.error:
  106.         return ""
  107.  
  108.     # Check for BSD hash
  109.     if magic in (0x00061561, 0x61150600):
  110.         return "dbhash"
  111.  
  112.     # Unknown
  113.     return ""
  114.  
  115. if __name__ == "__main__":
  116.     for filename in sys.argv[1:]:
  117.         print whichdb(filename) or "UNKNOWN", filename
  118.